home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / Apps / ArchiveUtils / nx_arc / arcmisc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-20  |  10.8 KB  |  536 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "arc.h"
  4. #ifdef MSDOS
  5. #include <dir.h>
  6. #endif
  7. #ifdef BSD
  8. #include <sys/types.h>
  9. #include <sys/dir.h>
  10. #endif
  11.  
  12. /* Miscellaneous routines to get ARC running on BSD 4.2... */
  13.  
  14.  
  15. char           *
  16. setmem(dest, size, c)
  17.     char           *dest;
  18.     unsigned INT    size;
  19.     char        c;
  20. {
  21.     unsigned INT    i;
  22.  
  23.     for (i = 0; i < size; dest[i] = c, i++);
  24.     return (&dest[0]);
  25. }
  26.  
  27. #ifdef MTS
  28. #define CUTOFF sepchr[0]
  29. #endif
  30. #ifdef MSDOS
  31. #define CUTOFF '\\'
  32. #endif
  33. #ifdef BSD
  34. #define CUTOFF '/'
  35. #endif
  36.  
  37. static          INT
  38. _makefn(source, dest)
  39.     unsigned char  *source;
  40.     unsigned char  *dest;
  41. {
  42.     INT             j;
  43.  
  44.     setmem(dest, 17, 0);    /* clear result field */
  45.     for (j = 0; *source && *source != '.'; ++source)
  46.         if (j < 8)
  47.             dest[j++] = *source;
  48.     for (j = 9; *source; ++source)
  49.         if (j < 13)
  50.             dest[j++] = *source;
  51. }
  52. /*
  53.  * make a file name using a template
  54.  */
  55.  
  56. char           *
  57. makefnam(rawfn, template, result)
  58.     unsigned char  *rawfn;    /* the original file name */
  59.     unsigned char  *template;    /* the template data */
  60.     unsigned char  *result;    /* where to place the result */
  61. {
  62.     unsigned char   et[17], er[17], rawbuf[100], *i, *rindex();
  63.  
  64.     *rawbuf = 0;
  65.     strcpy(rawbuf, rawfn);
  66. #ifdef MTS
  67.     i = rawbuf;
  68.     if (rawbuf[0] == tmpchr[0]) {
  69.         i++;
  70.         strcpy(rawfn, i);
  71.     } else
  72. #endif
  73.     if ((i = rindex(rawbuf, CUTOFF))) {
  74.         i++;
  75.         strcpy(rawfn, i);
  76.     }
  77. #ifdef MSDOS
  78.     else if ((i = rindex(rawbuf, ':'))) {
  79.         i++;
  80.         strcpy(rawfn, i);
  81.     }
  82. #endif
  83.     if (i)
  84.         *i = 0;
  85.     else
  86.         *rawbuf = 0;
  87.  
  88.     _makefn(template, et);
  89.     _makefn(rawfn, er);
  90.     *result = 0;        /* assure no data */
  91.     strcat(result, rawbuf);
  92.     strcat(result, er[0] ? er : et);
  93.     strcat(result, er[9] ? er + 9 : et + 9);
  94.     return ((char *) &result[0]);
  95. }
  96.  
  97. #if MSDOS
  98.  
  99. INT
  100. alphasort(dirptr1, dirptr2)
  101.     struct direct **dirptr1, **dirptr2;
  102. {
  103.     return (strcmp((*dirptr1)->d_name, (*dirptr2)->d_name));
  104. }
  105.  
  106. #endif
  107.  
  108. INT
  109. upper(string)
  110.     char           *string;
  111. {
  112.     char           *p;
  113.  
  114.     for (p = string; *p != NULL; p++)
  115.         if (islower(*p))
  116.             *p = toupper(*p);
  117. }
  118. INT
  119. arc_abort(s, arg1, arg2, arg3)
  120.     char           *s;
  121. {
  122.     fprintf(stderr, "ARC: ");
  123.     fprintf(stderr, s, arg1, arg2, arg3);
  124.     fprintf(stderr, "\n");
  125. #ifdef BSD
  126.     perror("BSD");
  127. #endif
  128.     exit(1);
  129. }
  130.  
  131. #ifndef MTS
  132.  
  133. char           *
  134. gcdir(dirname)
  135.     char           *dirname;
  136.  
  137. {
  138.     if (dirname == NULL || strlen(dirname) == 0)
  139.         dirname = (char *) malloc(1024);
  140.  
  141.     getwd(dirname);
  142. }
  143.  
  144. char           *pattern;    /* global so that fmatch can use them */
  145. INT             filemode;
  146.  
  147. char           *
  148. dir(filename, mode)        /* get files, one by one */
  149.     char           *filename;    /* template, or NULL */
  150.     INT             mode;    /* search mode bits */
  151. {
  152.     static struct direct **namelist;
  153.     static char   **NameList;
  154. #ifdef BSD
  155.     int             alphasort();
  156.     int             scandir();
  157. #endif    /* BSD */
  158.     int             fmatch();
  159.     static INT      Nnum = 0, ii;
  160.     char           *result = NULL;
  161.  
  162.     pattern = filename;
  163.     filemode = mode;    /* set up globals for fmatch */
  164.     if (Nnum == 0) {    /* first call */
  165.         Nnum = scandir(".", &namelist, fmatch, alphasort);
  166.         NameList = (char **) malloc(Nnum * sizeof(char *));
  167.         for (ii = 0; ii < Nnum; ii++) {
  168.             (NameList)[ii] = (char *) malloc(namelist[ii]->d_namlen + 1);
  169.             strcpy((NameList)[ii], namelist[ii]->d_name);
  170.         }
  171.         ii = 0;
  172.     }
  173.     if (ii >= Nnum) {    /* all out of files */
  174.         if (Nnum) {    /* there were some files found */
  175.             for (ii = 0; ii < Nnum; ii++)
  176.                 free(namelist[ii]);
  177.             free(namelist);
  178.         }
  179.         Nnum = 0;
  180.         return (NULL);
  181.     } else {
  182.         return ((NameList)[ii++]);
  183.     }
  184. }
  185.  
  186.  
  187. #define ASTERISK '*'        /* The '*' metacharacter */
  188. #define QUESTION '?'        /* The '?' metacharacter */
  189. #define LEFT_BRACKET '['    /* The '[' metacharacter */
  190. #define RIGHT_BRACKET ']'    /* The ']' metacharacter */
  191.  
  192. #define IS_OCTAL(ch) (ch >= '0' && ch <= '7')
  193.  
  194. typedef INT     BOOLEAN;
  195. #define VOID short
  196. #define TRUE 1
  197. #define FALSE 0
  198. #define EOS '\000'
  199.  
  200. static BOOLEAN  do_list();
  201. static char     nextch();
  202. static VOID     list_parse();
  203.  
  204.  
  205.  
  206. /*
  207.  * FUNCTION
  208.  * 
  209.  * do_list    process a list and following substring
  210.  * 
  211.  * SYNOPSIS
  212.  * 
  213.  * static BOOLEAN do_list (string, pattern) register char *string; register char
  214.  * *pattern;
  215.  * 
  216.  * DESCRIPTION
  217.  * 
  218.  * Called when a list is found in the pattern.  Returns TRUE if the current
  219.  * character matches the list and the remaining substring matches the
  220.  * remaining pattern.
  221.  * 
  222.  * Returns FALSE if either the current character fails to match the list or the
  223.  * list matches but the remaining substring and subpattern's don't.
  224.  * 
  225.  * RESTRICTIONS
  226.  * 
  227.  * The mechanism used to match characters in an inclusive pair (I.E. [a-d]) may
  228.  * not be portable to machines in which the native character set is not
  229.  * ASCII.
  230.  * 
  231.  * The rules implemented here are:
  232.  * 
  233.  * (1)  The backslash character may be used to quote any special character.
  234.  * I.E.  "\]" and "\-" anywhere in list, or "\!" at start of list.
  235.  * 
  236.  * (2)  The sequence \nnn becomes the character given by nnn (in octal).
  237.  * 
  238.  * (3)  Any non-escaped ']' marks the end of list.
  239.  * 
  240.  * (4)  A list beginning with the special character '!' matches any character
  241.  * NOT in list. The '!' character is only special if it is the first
  242.  * character in the list.
  243.  * 
  244.  */
  245.  
  246.  
  247.  
  248. /*
  249.  * PSEUDO CODE
  250.  * 
  251.  * Begin do_list Default result is no match Skip over the opening left bracket
  252.  * If the next pattern character is a '!' then List match gives FALSE Skip
  253.  * over the '!' character Else List match gives TRUE End if While not at
  254.  * closing bracket or EOS Get lower and upper bounds If character in bounds
  255.  * then Result is same as sense flag. Skip over rest of list End if End while
  256.  * If match found then If not at end of pattern then Call match with rest of
  257.  * pattern End if End if Return match result End do_list
  258.  * 
  259.  */
  260.  
  261. static          BOOLEAN
  262. do_list(string, pattern)
  263.     register char  *string;
  264.     char           *pattern;
  265. {
  266.     register BOOLEAN ismatch;
  267.     register BOOLEAN if_found;
  268.     register BOOLEAN if_not_found;
  269.     auto char       lower;
  270.     auto char       upper;
  271.  
  272.     pattern++;
  273.     if (*pattern == '!') {
  274.         if_found = FALSE;
  275.         if_not_found = TRUE;
  276.         pattern++;
  277.     } else {
  278.         if_found = TRUE;
  279.         if_not_found = FALSE;
  280.     }
  281.     ismatch = if_not_found;
  282.     while (*pattern != ']' && *pattern != EOS) {
  283.         list_parse(&pattern, &lower, &upper);
  284.         if (*string >= lower && *string <= upper) {
  285.             ismatch = if_found;
  286.             while (*pattern != ']' && *pattern != EOS) {
  287.                 pattern++;
  288.             }
  289.         }
  290.     }
  291.     if (*pattern++ != ']') {
  292.         fprintf(stderr, "warning - character class error\n");
  293.     } else {
  294.         if (ismatch) {
  295.             ismatch = match(++string, pattern);
  296.         }
  297.     }
  298.     return (ismatch);
  299. }
  300.  
  301.  
  302.  
  303. /*
  304.  * FUNCTION
  305.  * 
  306.  * list_parse    parse part of list into lower and upper bounds
  307.  * 
  308.  * SYNOPSIS
  309.  * 
  310.  * static VOID list_parse (patp, lowp, highp) char **patp; char *lowp; char
  311.  * *highp;
  312.  * 
  313.  * DESCRIPTION
  314.  * 
  315.  * Given pointer to a pattern pointer (patp), pointer to a place to store lower
  316.  * bound (lowp), and pointer to a place to store upper bound (highp), parses
  317.  * part of the list, updating the pattern pointer in the process.
  318.  * 
  319.  * For list characters which are not part of a range, the lower and upper bounds
  320.  * are set to that character.
  321.  * 
  322.  */
  323.  
  324. static          VOID
  325. list_parse(patp, lowp, highp)
  326.     char          **patp;
  327.     char           *lowp;
  328.     char           *highp;
  329. {
  330.     *lowp = nextch(patp);
  331.     if (**patp == '-') {
  332.         (*patp)++;
  333.         *highp = nextch(patp);
  334.     } else {
  335.         *highp = *lowp;
  336.     }
  337. }
  338.  
  339.  
  340.  
  341. /*
  342.  * FUNCTION
  343.  * 
  344.  * nextch    determine next character in a pattern
  345.  * 
  346.  * SYNOPSIS
  347.  * 
  348.  * static char nextch (patp) char **patp;
  349.  * 
  350.  * DESCRIPTION
  351.  * 
  352.  * Given pointer to a pointer to a pattern, uses the pattern pointer to
  353.  * determine the next character in the pattern, subject to translation of
  354.  * backslash-char and backslash-octal sequences.
  355.  * 
  356.  * The character pointer is updated to point at the next pattern character to be
  357.  * processed.
  358.  * 
  359.  */
  360.  
  361. static char
  362. nextch(patp)
  363.     char          **patp;
  364. {
  365.     register char   ch;
  366.     register char   chsum;
  367.     register INT    count;
  368.  
  369.     ch = *(*patp)++;
  370.     if (ch == '\\') {
  371.         ch = *(*patp)++;
  372.         if (IS_OCTAL(ch)) {
  373.             chsum = 0;
  374.             for (count = 0; count < 3 && IS_OCTAL(ch); count++) {
  375.                 chsum *= 8;
  376.                 chsum += ch - '0';
  377.                 ch = *(*patp)++;
  378.             }
  379.             (*patp)--;
  380.             ch = chsum;
  381.         }
  382.     }
  383.     return (ch);
  384. }
  385.  
  386. /*
  387.  * Filename match - here, * matches everything
  388.  */
  389.  
  390. int
  391. fmatch(direntry)
  392.     struct direct  *direntry;
  393. {
  394.     char           *ptr, *string;
  395.  
  396.     string = direntry->d_name;
  397.  
  398.     if (!strcmp(pattern, "") || !strcmp(pattern, "*.*") || !strcmp(pattern, "*"))
  399.         return (1);
  400.     return (match(string, pattern));
  401. }
  402. #else
  403. /* dir code for MTS under Bell Labs C... */
  404.  
  405. char           *
  406. dir(filepattern, junk)
  407.     char           *filepattern;    /* template or NULL */
  408.     INT             junk;    /* unused on MTS */
  409. {
  410.     char           *malloc(), *index();
  411. #ifdef USECATSCAN
  412.     fortran         catscan(), fileinfo();
  413.  
  414.     struct catname {
  415.         short           len;
  416.         char            name[257];
  417.     }               pattern;
  418.  
  419.     struct catval {
  420.         int             maxlen;
  421.         int             actlen;
  422.         char            name[257];
  423.     }               catreturn;
  424.  
  425.     char           *i;
  426.     int             j, RETCODE;
  427.  
  428.     static int      catptr = 0;
  429.     static int      catflag = 0x200;
  430.     static int      cattype = 1;
  431.     static int      patflag = 0;
  432.  
  433.     catreturn.maxlen = 256;
  434.  
  435.     if (patflag) {
  436.         patflag = 0;
  437.         catptr = 0;
  438.         return (NULL);
  439.     }
  440.     if (filepattern) {
  441.         strcpy(pattern.name, filepattern);
  442.         pattern.len = strlen(filepattern);
  443.         if (!index(filepattern, '?'))
  444.             patflag = 1;
  445.     }
  446.     if (patflag) {
  447.         fileinfo(&pattern, &cattype, "CINAME  ", &catreturn, _retcode RETCODE);
  448.         catptr = RETCODE ? 0 : 1;
  449.     } else
  450.         catscan(&pattern, &catflag, &cattype, &catreturn, &catptr);
  451.  
  452.     if (!catptr)
  453.         return (NULL);
  454.     else {
  455.         char           *k;
  456.  
  457.         k = index(catreturn.name, ' ');
  458.         if (k)
  459.             *k = 0;
  460.         else {
  461.             j = catreturn.actlen;
  462.             catreturn.name[j] = 0;
  463.         }
  464.         k = catreturn.name;
  465.         if (catreturn.name[0] == tmpchr[0])
  466.             k++;
  467.         else if ((k = index(catreturn.name, sepchr[0])))
  468.             k++;
  469.         else
  470.             k = catreturn.name;
  471.         j = strlen(k);
  472.         i = malloc(++j);
  473.         strcpy(i, k);
  474.         return (i);
  475.     }
  476. #else
  477.     fortran         gfinfo();
  478.     static char     gfname[24];
  479.     static char     pattern[20];
  480.     static int      gfdummy[2] = {
  481.                       0, 0
  482.     },              gfflags;
  483.     int             i, RETCODE;
  484.     char           *j, *k;
  485.  
  486.     if (filepattern) {
  487.         strcpy(pattern, filepattern);
  488.         strcat(pattern, " ");
  489.         for (i = 20; i < 24; i++)
  490.             gfname[i] = '\0';
  491.         if (index(pattern, '?'))
  492.             gfflags = 0x0C;
  493.         else
  494.             gfflags = 0x09;
  495.     } else if (gfflags == 0x09)
  496.         return (NULL);
  497.  
  498.     gfinfo(pattern, gfname, &gfflags, gfdummy, gfdummy, gfdummy, _retcode RETCODE);
  499.     if (RETCODE)
  500.         return (NULL);
  501.     else {
  502.         k = index(gfname, ' ');
  503.         *k = '\0';
  504.         k = gfname;
  505.         if (gfname[0] == tmpchr[0])
  506.             k++;
  507.         else if ((k = index(gfname, sepchr[0])))
  508.             k++;
  509.         else
  510.             k = gfname;
  511.         i = strlen(k);
  512.         j = malloc(++i);
  513.         strcpy(j, k);
  514.         return (j);
  515.     }
  516. #endif
  517. }
  518.  
  519. unlink(path)
  520.     char           *path;    /* name of file to delete */
  521. {
  522.     fortran         destroy();
  523.     int        RETCODE;
  524.  
  525.     char            name[258];
  526.  
  527.     strcpy(name, path);
  528.     strcat(name, " ");
  529.     destroy(name, _retcode RETCODE);
  530.     if (RETCODE)
  531.         return (-1);
  532.     else
  533.         return (0);
  534. }
  535. #endif
  536.